package com.xcity.game.activity.newplayer;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import com.xcity.db.entity.Player;
import com.xcity.game.activity.ActivityService;
import com.xcity.game.activity2.ActivityIds;
import com.xcity.game.battle.pve.PVEManager;
import com.xcity.game.battle.pve.PVEStage;
import com.xcity.game.common.Cause;
import com.xcity.game.common.MessageConst;
import com.xcity.game.event.GameEvents;
import com.xcity.game.player.PlayerService;
import com.xcity.pomelo.PomeloRoute;
import com.xcity.pomelo.push.msg.ActivityStatePush;
import com.xcity.pomelo.request.ActivityNewPlayerDayShopListRequest;
import com.xcity.pomelo.request.ActivityNewPlayerGetRewardRequest;
import com.xcity.pomelo.request.ActivityNewPlayerHalfShopListRequest;
import com.xcity.pomelo.request.ActivityNewPlayerInfoRequest;
import com.xcity.pomelo.request.ActivityNewPlayerShopBuyRequest;
import com.xcity.pomelo.request.ActivityNewPlayerViewRequest;
import com.xcity.pomelo.response.ActivityNewPlayerDayShopListResponse;
import com.xcity.pomelo.response.ActivityNewPlayerGetRewardResponse;
import com.xcity.pomelo.response.ActivityNewPlayerHalfShopListResponse;
import com.xcity.pomelo.response.ActivityNewPlayerInfoResponse;
import com.xcity.pomelo.response.ActivityNewPlayerShopBuyResponse;
import com.xcity.pomelo.response.ActivityNewPlayerViewResponse;
import com.xcity.pomelo.response.HintResponse;

import gnu.trove.map.hash.TIntObjectHashMap;
import naga.x.App;
import naga.x.event.Event;
import naga.x.event.EventListener;
import naga.x.game.template.TemplateService;
import naga.x.game.time.DayListener;
import naga.x.game.time.TimeUpdater;
import naga.x.net.Session;
import naga.x.net.annotation.OPHandler;
import naga.x.net.impl.pomelo.annotation.PomeloOP;
import naga.x.service.ServiceException;
import naga.x.util.TimeUtils;

/**
 * 开服狂欢 (新角色7天活动)
 * @author shipeng.zhu
 */
@OPHandler
public class ActivityNewPlayerService extends ActivityService implements EventListener, DayListener{

	public static boolean INIT = false;
	/**
	 * exp:	9号 10:00创建的角色
	 * 		17号0点以后就不再统计活动目标了
	 */
	public static int COUNT_DAY = 8;
	/**
	 * exp:	9号 10:00创建的角色
	 *		20号0点以后就不能再领奖了
	 */
	public static int REWARD_DAY = 10;
	
	public static byte TABTYPE_DAY_SHOP = 4;
	public static byte FUNC_TYPE_DAY_SHOP = 18;//每日热卖活动目标类型
	public static byte TABTYPE_HALF_SHOP = 5;
	public static byte FUNC_TYPE_HALF_SHOP = 19;//半价抢购活动目标类型
	protected static List<NewPlayerTaskTemplate> taskTempList = new ArrayList<NewPlayerTaskTemplate>();
	protected static TIntObjectHashMap<NewPlayerShopTemplate> id2shopItem = new TIntObjectHashMap<NewPlayerShopTemplate>();
	protected static List<NewPlayerShopTemplate> dayShopList = new ArrayList<NewPlayerShopTemplate>();
	protected static List<NewPlayerShopTemplate> halfShopList = new ArrayList<NewPlayerShopTemplate>();
	protected static List<NewPlayerViewTemplate> viewList = new ArrayList<NewPlayerViewTemplate>();
	
	@Override
	public void startup() throws ServiceException {
		App.getApp().getEventManager().register(this);
		TemplateService ts = App.getApp().getServiceManager().get(TemplateService.class);
		taskTempList.clear();
		List<NewPlayerTaskTemplate> temList = ts.getTemplatesList(NewPlayerTaskTemplate.class);
		for(int i = 0; i < temList.size(); i++){
			NewPlayerTaskTemplate t = temList.get(i);
			if(t.getBan() == 0){
				taskTempList.add(t);
			}
		}
		
		
		id2shopItem.clear();
		List<NewPlayerShopTemplate> shopList = ts.getTemplatesList(NewPlayerShopTemplate.class);
		for(int i = 0; i < shopList.size(); i++){
			NewPlayerShopTemplate t = shopList.get(i);
			id2shopItem.put(t.getId(), t);
		}
		
		dayShopList.clear();
		halfShopList.clear();
		for(int i = 0; i < taskTempList.size(); i++){
			NewPlayerTaskTemplate t = temList.get(i);
			if(t.getTab() == TABTYPE_DAY_SHOP && t.getType() == FUNC_TYPE_DAY_SHOP){
				NewPlayerShopTemplate te = id2shopItem.get(t.getParam()[0]);
				if(te != null){
					dayShopList.add(te);
				}
			}else if(t.getTab() == TABTYPE_HALF_SHOP && t.getType() == FUNC_TYPE_HALF_SHOP){
				NewPlayerShopTemplate te = id2shopItem.get(t.getParam()[0]);
				if(te != null){
					dayShopList.add(te);
				}
			}
		}
		viewList.clear();
		viewList = new ArrayList<NewPlayerViewTemplate>(ts.getTemplatesList(NewPlayerViewTemplate.class));
		INIT = true;
	}

	@Override
	public void shutdown() throws ServiceException {
		INIT = false;
	}

	@Override
	public int[] getEventTypes() {
		return new int[]{
			GameEvents.EVENT_PLAYER_LOADED,
			GameEvents.EVENT_PLAYER_LOGIN,
			GameEvents.EVENT_RECHARGE,
			GameEvents.EVENT_RECHARGE_OFFLINE,
			GameEvents.EVENT_PLAYER_LEVEL_UP,
			GameEvents.EVENT_FIX_ASSETS_CHANGED,
			GameEvents.EVENT_EMPLOYEE_ADDED,
			GameEvents.EVENT_ARENA_WIN,
			GameEvents.EVENT_EMPLOYEE_STAR_UP,
			GameEvents.EVENT_EMPLOYEE_LEVEL_UP,
			GameEvents.EVENT_EQUIP_ADD,
			GameEvents.EVENT_EQUIP_SUIT_ADD,
			GameEvents.EVENT_EMPLOYEE_QUALITY_UP,
			GameEvents.EVENT_EQUIP_LVL_UP,
			GameEvents.EVENT_PVE_SUCCESS,
			GameEvents.EVENT_ADD_FRIEND,
			GameEvents.EVENT_ADVENTURE_PLAY,
			GameEvents.EVENT_EQUIP_ENHANCE,
			GameEvents.EVENT_SWEEP_DONE,
		};
	}

	@Override
	public void handleEvent(Event event) {
		Player player = event.getParameter(0);
		switch (event.getType()) {
		case GameEvents.EVENT_PLAYER_LOADED:
			playerLoaded(event.getParameter(0));
			break;
		case GameEvents.EVENT_PLAYER_LOGIN:
			playerLogin(event.getParameter());
			player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.DAY_LOGIN, event.getParameters());
			player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.FRIEND_COUNT, event.getParameters());
			break;
		case GameEvents.EVENT_RECHARGE:
		case GameEvents.EVENT_RECHARGE_OFFLINE:
			player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.RECHARGE, event.getParameters());
			break;
		case GameEvents.EVENT_PLAYER_LEVEL_UP:
			player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.PLAYER_LVLUP, event.getParameters());
			break;
		case GameEvents.EVENT_FIX_ASSETS_CHANGED:
			player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.FIX_ASSETS, event.getParameters());
			player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.FIX_ASSETS_10K, event.getParameters());
			player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.FIX_ASSETS_100M, event.getParameters());
			break;
		case GameEvents.EVENT_EMPLOYEE_ADDED:
			player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.EMPLOYEE_COUNT, event.getParameters());
			break;
		case GameEvents.EVENT_ARENA_WIN:
			player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.ARENA_RANK, event.getParameters());
			break;
		case GameEvents.EVENT_EMPLOYEE_STAR_UP:
			player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.EMPLOYEE_STAR, event.getParameters());
			break;
		case GameEvents.EVENT_EMPLOYEE_LEVEL_UP:
			player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.EMPLOYEE_LVL, event.getParameters());
			break;
		case GameEvents.EVENT_EQUIP_ADD:
			player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.EQUIP_COUNT, event.getParameters());
			break;
		case GameEvents.EVENT_EQUIP_SUIT_ADD:
			player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.EQUIP_SUIT_COUNT, event.getParameters());
			break;
		case GameEvents.EVENT_EMPLOYEE_QUALITY_UP:
			player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.EMPLOYEE_QUALITY, event.getParameters());
			break;
		case GameEvents.EVENT_EQUIP_LVL_UP:
			player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.EQUIP_LVL, event.getParameters());
			break;
		case GameEvents.EVENT_PVE_SUCCESS:
			PVEStage stage = (PVEStage)event.getParameter(1);
			if(stage.getTemplate().getType() == PVEManager.STAGE_TYPE_HERO){
				player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.HERO_STAGE_DONE, event.getParameters());
				player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.HERO_COUNT, player, 1);
			}else{
				player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.NORMAL_STAGE_DONE, event.getParameters());
				player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.NORMAL_COUNT, player, 1);
			}
			break;
		case GameEvents.EVENT_SWEEP_DONE:
			int type = (Byte)event.getParameter(2);
			int count = event.getParameter(3);
			if(type == PVEManager.STAGE_TYPE_HERO){
				player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.HERO_COUNT, player, count);
			}else{
				player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.NORMAL_COUNT, player, count);
			}
			break;
		case GameEvents.EVENT_ADD_FRIEND:
			player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.FRIEND_COUNT, event.getParameters());
			break;
		case GameEvents.EVENT_ADVENTURE_PLAY:
			player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.ADVENTURE_COUNT, event.getParameters());
			break;
		case GameEvents.EVENT_EQUIP_ENHANCE:
			player.getNewPlayerTasks().handleOnChange(NewPlayerTracer.EQUIP_LVL, event.getParameters());
			break;
		}
	}
	
	public static List<NewPlayerTaskTemplate> getTaskTempList() {
		return taskTempList;
	}
	
	public void playerLogin(Player player){
		int today = TimeUpdater.getInstance().today();
		int creatDay = TimeUtils.ofDay(player.getCreateTime().getTime());
		if(!TimeUtils.checkDayDuring(creatDay, today, REWARD_DAY + 1)){//today > creatDay + REWARD_DAY
			if(player.getNewPlayerTasks().taskList.size() > 0){
				player.getNewPlayerTasks().clearPool();
				player.getNewPlayerTasks().taskList.clear();
			}
		}
	}
	
	public void playerLoaded(Player player){
		if(player.getNewPlayerTasks().checkInActive()){
			player.send(new ActivityStatePush(ActivityIds.ACTIVITY_NEWPLAYER, STATE_OPENED));
		}
	}
	
	@PomeloOP(PomeloRoute.ACTIVITY_NEWPLAYER_SHOP_BUY)
	public void requestShopBuy(Session session, ActivityNewPlayerShopBuyRequest req){
		Player player = session.getClient();
		if(!player.getNewPlayerTasks().checkInActive()){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_ENDED));
			return;
		}
		NewPlayerTask task = player.getNewPlayerTasks().getTaskByTempId(req.getActiveIndex());
		if(task == null){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_ENDED));
			return;
		}
		NewPlayerTaskTemplate taskTemp = task.getTemplate();
		if(taskTemp == null){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_ENDED));
			return;
		}
		if(!(taskTemp.getTab() == TABTYPE_DAY_SHOP && taskTemp.getType() == FUNC_TYPE_DAY_SHOP && req.getTabType() == TABTYPE_DAY_SHOP) &&
				!(taskTemp.getTab() == TABTYPE_HALF_SHOP && taskTemp.getType() == FUNC_TYPE_HALF_SHOP && req.getTabType() == TABTYPE_HALF_SHOP)){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_NEWPLAYER_NO_ITEM));
			return;
		}
		int nowday = TimeUtils.getDayGap(player.getNewPlayerTasks().getCreatDay(), TimeUpdater.getInstance().today()) + 1;//TimeUpdater.getInstance().today() - player.getNewPlayerTasks().getCreatDay() + 1;
		if(nowday < taskTemp.getStartDay()){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_NEWPLAYER_SHOP_ERROR_DAY));
			return;
		}
		NewPlayerShopTemplate shopTemp = id2shopItem.get(taskTemp.getParam()[0]);
		if(shopTemp == null){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_NEWPLAYER_NO_ITEM));
			return;
		}
		int reqBuyCount = req.getCount();//请求购买次数
		int totalCount = shopTemp.getCount();
		int[] progress = task.getProgress();//已购买次数
		if(progress[0] + reqBuyCount > totalCount){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_NEWPLAYER_NOT_ENOUGH_ITEM));
			return;
		}
		if(!player.costStone(shopTemp.getPrice() * reqBuyCount, Cause.NP_SHOP)){
			player.send(new HintResponse(req.getSerial(), MessageConst.STONE_NOT_ENOUTH));
			return;
		}
		progress[0] = progress[0] + reqBuyCount;
		if(progress[0] > totalCount){
			progress[0] = totalCount;
		}
		player.getBag().addItemOrSendMail(shopTemp.getItemId(), shopTemp.getItemCount() * reqBuyCount, Cause.NP_SHOP);
		player.send(new ActivityNewPlayerShopBuyResponse(req.getSerial(), task));
		return;
	}

	@PomeloOP(PomeloRoute.ACTIVITY_NEWPLAYER_INFO)
	public void requestInfo(Session session, ActivityNewPlayerInfoRequest req){
		Player player = session.getClient();
		if(!player.getNewPlayerTasks().checkInActive()){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_ENDED));
			return;
		}
		int today = TimeUpdater.getInstance().today();
		int currentDay = TimeUtils.getDayGap(player.getNewPlayerTasks().getCreatDay(), today) + 1;//today - player.getNewPlayerTasks().getCreatDay() + 1;
		int day = req.getDay();
		if(day == -1){
			day = currentDay;
			if(day > ActivityNewPlayerService.COUNT_DAY - 1){
				day = ActivityNewPlayerService.COUNT_DAY - 1;
			}
		}
		if(day < 1 || day > ActivityNewPlayerService.REWARD_DAY || day > currentDay){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_NEWPLAYER_WRONG_DAY));
			return;
		}
		int day7reward = -1;
		for(int i = viewList.size() - 1; i > -1; i--){
			NewPlayerViewTemplate temp = viewList.get(i);
			if(temp.getId() == 7){
				day7reward = temp.getReward1()[2];
				break;
			}
		}
		player.send(new ActivityNewPlayerInfoResponse(req.getSerial(), player, day, day7reward));
	}
	
	@PomeloOP(PomeloRoute.ACTIVITY_NEWPLAYER_VIEW)
	public void requestView(Session session, ActivityNewPlayerViewRequest req){
		Player player = session.getClient();
		if(!player.getNewPlayerTasks().checkInActive()){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_ENDED));
			return;
		}
		int day = req.getDay();
		if(day < 2 || day > ActivityNewPlayerService.COUNT_DAY){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_NEWPLAYER_WRONG_DAY));
			return;
		}
		player.send(new ActivityNewPlayerViewResponse(req.getSerial(), day, viewList));
	}
	
	@PomeloOP(PomeloRoute.ACTIVITY_NEWPLAYER_DAY_SHOP_LIST)
	public void requestDayShopList(Session session, ActivityNewPlayerDayShopListRequest req){
		Player player = session.getClient();
		if(!player.getNewPlayerTasks().checkInActive()){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_ENDED));
			return;
		}
		player.send(new ActivityNewPlayerDayShopListResponse(req.getSerial(), player));
	}
	
	@PomeloOP(PomeloRoute.ACTIVITY_NEWPLAYER_HALF_SHOP_LIST)
	public void requestDayShopList(Session session, ActivityNewPlayerHalfShopListRequest req){
		Player player = session.getClient();
		if(!player.getNewPlayerTasks().checkInActive()){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_ENDED));
			return;
		}
		int day = req.getDay();
		if(day < 1 || day > ActivityNewPlayerService.COUNT_DAY){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_NEWPLAYER_WRONG_DAY));
			return;
		}
		player.send(new ActivityNewPlayerHalfShopListResponse(req.getSerial(), player, day));
	}
	
	@PomeloOP(PomeloRoute.ACTIVITY_NEWPLAYER_GET_REWARD)
	public void requestGetReward(Session session, ActivityNewPlayerGetRewardRequest req){
		Player player = session.getClient();
		if(!player.getNewPlayerTasks().checkInActive()){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_ENDED));
			return;
		}
		NewPlayerTask task = player.getNewPlayerTasks().getTaskByTempId(req.getActiveIndex());
		if(task == null){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_ENDED));
			return;
		}
		NewPlayerTaskTemplate taskTemp = task.getTemplate();
		if(taskTemp == null){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_ENDED));
			return;
		}
		int nowday = TimeUtils.getDayGap(player.getNewPlayerTasks().getCreatDay(), TimeUpdater.getInstance().today()) + 1;//TimeUpdater.getInstance().today() - player.getNewPlayerTasks().getCreatDay() + 1;
		if(nowday < taskTemp.getStartDay()){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_NEWPLAYER_ERROR_DAY));
			return;
		}
		if(task.getState() == NewPlayerTask.State.DOING){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_NEWPLAYER_NOT_DONE));
			return;
		}
		if(task.getState() == NewPlayerTask.State.GOT){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_NEWPLAYER_ALREADY_GOT));
			return;
		}
		//发奖励
		if(taskTemp.getMoney() > 0){
			player.addGold(taskTemp.getMoney(), Cause.NP_REWARD);
		}
		if(taskTemp.getStone() > 0){
			player.addStone(taskTemp.getStone(), Cause.NP_REWARD);
		}
		for(int i = 0; i < taskTemp.getItemIds().length; i++){
			int itemid = taskTemp.getItemIds()[i];
			int itemcount = taskTemp.getItemCounts()[i];
			if(itemid > 0 && itemcount > 0){
				player.getBag().addItemOrSendMail(itemid, itemcount, Cause.NP_REWARD);
			}
		}
		task.setState(NewPlayerTask.State.GOT);
		ActivityNewPlayerGetRewardResponse response = new ActivityNewPlayerGetRewardResponse(req.getSerial(), task);
		player.send(response);
		LOG.info("[NEWPLAYER_GOT]ID[{}]TID[{}]STATE[{}]PARAM1[{}]PARAM2[{}]PARAM3[{}]", player.getId(), task.getTemplate().getId(), task.getState().ordinal(), task.getProgress()[0], task.getProgress()[1], task.getProgress()[2]);
	}

	@Override
	public boolean dayChanged() {
		Collection<Player> players = App.getApp().getServiceManager().get(PlayerService.class).getOnlinePlayers();
		for(Player player : players){
			if(!player.getNewPlayerTasks().checkInActive()){
				player.send(new ActivityStatePush(ActivityIds.ACTIVITY_NEWPLAYER, STATE_CLOSED));
			}
		}
		return true;
	}
}
